package com.sunshine.util.minio;

import io.minio.*;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * MinIO工具类
 * 用于处理文件上传到MinIO对象存储服务
 */
@Component
public class MinIOUtil {
    
    @Resource
    private MinioClient minioClient;
    
    @Value("${minio.bucketName}")
    private String bucketName;
    
    /**
     * 检查存储桶是否存在，如果不存在则创建它
     *
     * @throws Exception 当创建存储桶过程中发生错误时抛出异常
     */
    public void createBucketIfNotExists() throws Exception {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            throw new RuntimeException("存储桶检查/创建失败: " + e.getMessage());
        }
    }
    
    /**
     * 上传单个文件到MinIO
     *
     * @param file 要上传的文件
     * @param folder 文件存储的文件夹路径
     * @return 文件访问URL
     * @throws Exception 上传过程中可能发生的异常
     */
    public String uploadFile(MultipartFile file, String folder) throws Exception {
        // 检查文件是否为空
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }
        
        InputStream inputStream = null;
        try {
            // 生成唯一的对象名称，避免文件名冲突
            String originalFilename = file.getOriginalFilename();
            String fileExtension = "";
            if (originalFilename != null && originalFilename.lastIndexOf(".") != -1) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String objectName = folder + System.currentTimeMillis() + "_" + UUID.randomUUID().toString() + fileExtension;
            
            // 获取文件输入流
            inputStream = file.getInputStream();
            
            // 上传文件到 MinIO
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            
            minioClient.putObject(args);
            
            // 返回访问 URL
            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(objectName)
                            .expiry(7, TimeUnit.DAYS) // 签名链接有效期7天
                            .build()
            );
        } finally {
            // 确保输入流被正确关闭
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    // 记录日志但不中断操作
                }
            }
        }
    }
    
    /**
     * 上传单个文件到MinIO（使用默认文件夹）
     *
     * @param file 要上传的文件
     * @return 文件访问URL
     * @throws Exception 上传过程中可能发生的异常
     */
    public String uploadFile(MultipartFile file) throws Exception {
        return uploadFile(file, "default/");
    }
    
    /**
     * 批量上传文件到MinIO
     *
     * @param files 要上传的文件列表
     * @param folder 文件存储的文件夹路径
     * @return 文件访问URL列表
     * @throws Exception 上传过程中可能发生的异常
     */
    public List<String> uploadFiles(MultipartFile[] files, String folder) throws Exception {
        List<String> urls = new ArrayList<>();
        for (MultipartFile file : files) {
            if (file != null && !file.isEmpty()) {
                String url = uploadFile(file, folder);
                urls.add(url);
            }
        }
        return urls;
    }
    
    /**
     * 批量上传文件到MinIO（使用默认文件夹）
     *
     * @param files 要上传的文件列表
     * @return 文件访问URL列表
     * @throws Exception 上传过程中可能发生的异常
     */
    public List<String> uploadFiles(MultipartFile[] files) throws Exception {
        return uploadFiles(files, "default/");
    }
    
    /**
     * 删除MinIO中的文件
     *
     * @param objectName 对象名称
     * @throws Exception 删除过程中可能发生的异常
     */
    public void deleteFile(String objectName) throws Exception {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build());
    }
    
    /**
     * 批量删除MinIO中的文件
     *
     * @param objectNames 对象名称列表
     * @throws Exception 删除过程中可能发生的异常
     */
    public void deleteFiles(List<String> objectNames) throws Exception {
        for (String objectName : objectNames) {
            deleteFile(objectName);
        }
    }
}